<template>
  <div
    class="lottery hideScrollBar"
    :class="{ 'lottery-fri': lotteryStore.isFri }"
    ref="scrollEl"
  >
    <!-- 背景图片 -->
    <div
      v-show="lottery"
      class="lottery-bg"
      :class="{
        'lottery-bg-end':
          lotteryStore.activityCurStatus == 3 ||
          lotteryStore.activityCurStatus == 5,
        'lottery-bg-fri': lotteryStore.isFri,
      }"
    />
    <!-- 导航 -->
    <NavBar
      isFixed
      :title="`${$t('lotteryMoney.cjdyj')} 2.0`"
      isTransparent
      :navScorllOffset="60"
      navScorllColor="#fff"
      :scrollEl="scrollEl"
      :customBackFn="handleBack"
      :customCloseFn="handleClose"
    />
    <!-- 骨架屏 -->
    <template v-if="!lottery">
      <van-skeleton title :row="3" style="margin-top: 25px" />
      <van-skeleton style="margin-top: 25px">
        <template #template>
          <div :style="{ display: 'flex', width: '100%' }">
            <van-skeleton-image />
            <div :style="{ flex: 1, marginLeft: '16px' }">
              <van-skeleton-paragraph row-width="60%" />
              <van-skeleton-paragraph />
              <van-skeleton-paragraph />
            </div>
          </div>
        </template>
      </van-skeleton>
    </template>
    <!-- 内容 -->
    <template v-else>
      <!-- 活动 -->
      <div class="content">
        <!-- 网络异常: 1.查询数据的请求超时，失败 2.socket 6 次链接失败 -->
        <div
          v-if="sessionStatus == 4 || isThredFail"
          class="lottery-wait items-center"
          :class="{ 'lottery-wait-sun': lotteryStore.isFri }"
          @click="refreshClick"
        >
          <div
            class="lottery-wait-text items-center"
            :class="{ 'lottery-wait-text-sun': lotteryStore.isFri }"
          >
            <img
              v-if="lotteryStore.isFri"
              class="lottery-wait-icon"
              src="/image/gth1.svg"
            />
            <img v-else class="lottery-wait-icon" src="/image/gth0.svg" />
            {{ $t("lotteryMoney.jszqsd") }}
          </div>
          <img
            v-if="lotteryStore.isFri"
            class="lottery-wait-btn"
            src="/image/refresh1.svg"
          />
          <img v-else class="lottery-wait-btn" src="/image/refresh.svg" />
        </div>
        <ClientOnly>
          <van-pull-refresh
            class="pull-refresh"
            v-model="refreshLoading"
            :pulling-text="t('mvp.other.text9')"
            :loosing-text="t('mvp.other.text10')"
            loading-text=" "
            @refresh="onRefreshRequest"
          >
            <!-- 兑奖 -->
            <img
              v-if="!lotteryStore.isFri"
              class="lottery-redemption items-center"
              @click="jumpPage('bdcToMoney')"
              src="/image/lottery-v3/redemption-icon.svg"
            />
            <img
              v-else
              class="lottery-redemption items-center"
              @click="jumpPage('bdcToMoney')"
              src="/image/lottery-v3/redemption1-icon.svg"
            />
            <!-- 活动说明 -->
            <img
              v-if="!lotteryStore.isFri"
              class="lottery-desc"
              @click="jumpPage('lotteryDesc')"
              src="/image/lottery-v3/desc-icon.svg"
            />
            <img
              v-else
              class="lottery-desc"
              @click="jumpPage('lotteryDesc')"
              src="/image/lottery-v3/desc1-icon.svg"
            />
            <!-- 日期 -->
            <div class="date">
              <!-- 周一到周日 -->
              <div
                class="date-week items-center"
                :class="{
                  'date-week-fri': lotteryStore.isFri,
                }"
              >
                <div
                  v-for="(item, index) in day7"
                  :key="index"
                  class="date-item items-center"
                  :class="{
                    'date-item-cur': item.isToDay && !item.isJh && item.id != 7, // 今天,但没有选择今天
                    'date-item-jh': item.isJh && item.id != 7, // 选择了那一天,除了周五
                    'date-item-fri': item.id == 7 && !item.isJh, // 周五没有被选择的样式
                    'date-item-fri-jh': item.id == 7 && item.isJh, // 选择了周五
                  }"
                  @click.stop="changeDay(item.id)"
                >
                  <!-- 选中背景 -->
                  <img
                    v-if="item.isJh && item.id != 7"
                    class="date-item-sub-jhbg"
                    src="/image/lottery-v3/date-jh-bg.svg"
                  />
                  <img
                    v-else-if="item.isJh && item.id == 7"
                    class="date-item-sub-jhbg"
                    src="/image/lottery-v3/date-jhFri-bg.svg"
                  />
                  <!-- 周几 -->
                  <div
                    class="date-item-sub"
                    :class="{
                      'date-item-sub-jh': toDayIdx == index + 1 && item.id != 7,
                    }"
                  >
                    {{ item.title }}
                  </div>
                  <!-- 周五 tag -->
                  <template v-if="item.id == 7">
                    <img
                      v-if="globalStore.$state.language == 'VI'"
                      class="date-item-fri-tag"
                      src="/image/lottery-v3/super-fri-en.png"
                    />
                    <img
                      v-else-if="globalStore.$state.language == 'pt'"
                      class="date-item-fri-tag"
                      src="/image/lottery-v3/super-fri-vi.png"
                    />
                    <img
                      v-else
                      class="date-item-fri-tag"
                      src="/image/lottery-v3/super-fri-pt.png"
                    />
                  </template>
                </div>
              </div>
              <!-- 阴影 -->
              <div
                class="date-shadow"
                :class="{
                  'date-shadow-fri': lotteryStore.isFri,
                }"
              ></div>
            </div>
            <!-- 奖池 -->
            <Jackpot
              :source="pool"
              :moneyEnd="moneyEnd"
              :moneyStart="moneyStart"
            ></Jackpot>
            <!-- 手动关闭活动 -->
            <div v-if="lotteryStore.activityCurStatus == 0" class="box">
              <WinningRecord @call="isShowWinDesc = true"></WinningRecord>
              <InviteFriendsView
                :source="InviteFriendsViewSource"
              ></InviteFriendsView>
              <WinningHistoryRecord></WinningHistoryRecord>
            </div>
            <!-- 未开始 -->
            <div v-if="lotteryStore.activityCurStatus == 1" class="box">
              <WinningRecord @call="isShowWinDesc = true"></WinningRecord>
              <InviteFriendsReward
                v-if="isShowInviteFriendsRewardView"
                :source="inviteFriendsOnceReward"
                @click.stop="inviteFriendsRewardClick"
              ></InviteFriendsReward>
              <InviteFriendsView
                :source="InviteFriendsViewSource"
              ></InviteFriendsView>
              <WinningHistoryRecord></WinningHistoryRecord>
            </div>
            <!-- 进行中 -->
            <div v-if="lotteryStore.activityCurStatus == 2" class="box">
              <WinningRecord @call="isShowWinDesc = true"></WinningRecord>
              <InviteFriendsReward
                v-if="isShowInviteFriendsRewardView"
                :source="inviteFriendsOnceReward"
                @click.stop="inviteFriendsRewardClick"
              ></InviteFriendsReward>
              <InviteFriendsView
                :source="InviteFriendsViewSource"
              ></InviteFriendsView>
              <WinningHistoryRecord></WinningHistoryRecord>
            </div>
            <!-- 开奖中 -->
            <div v-if="lotteryStore.activityCurStatus == 3" class="">
              <winningResult @countdownEnd="countdownCall"></winningResult>
            </div>
            <!-- 已结束 -->
            <div v-if="lotteryStore.activityCurStatus == 5">
              <winningResult :source="winningResultInfo"></winningResult>
            </div>
            <!-- 我的下注记录,往期抽奖 -->
            <div class="record items-center">
              <!-- 我的下注 -->
              <div
                v-if="Number(lotteryStore.activityCurStatus) <= 3"
                class="record-item items-center"
                :class="{
                  'record-item-fri': lotteryStore.isFri,
                }"
                @click="jumpPage('myBetRecord')"
              >
                <img
                  v-if="!lotteryStore.isFri"
                  class="record-item-icon"
                  src="/image/lottery-v3/bqxzjl-icon.svg"
                />
                <img
                  v-else
                  class="record-item-icon"
                  src="/image/lottery-v3/bqxzjl1-icon.svg"
                />
                <div class="record-item-text">
                  {{ $t("lotteryMoney.wdxz") }}
                </div>
              </div>
              <!-- 往期抽奖 -->
              <div
                v-if="Number(lotteryStore.activityCurStatus) <= 3"
                class="record-item items-center"
                :class="{
                  'record-item-fri': lotteryStore.isFri,
                }"
                @click="jumpPage('previousDraws')"
              >
                <img
                  v-if="!lotteryStore.isFri"
                  class="record-item-icon"
                  src="/image/lottery-v3/wqcjjl-icon.svg"
                />
                <img
                  v-else
                  class="record-item-icon"
                  src="/image/lottery-v3/wqcjjl1-icon.svg"
                />
                <div class="record-item-text">
                  {{ $t("lotteryMoney.wqcj") }}
                </div>
              </div>
              <!-- 中奖记录 -->
              <div
                v-if="Number(lotteryStore.activityCurStatus) == 5"
                class="record-item items-center"
                :class="{
                  'record-item-fri': lotteryStore.isFri,
                }"
                @click="jumpPage('winDetails')"
              >
                <img
                  v-if="!lotteryStore.isFri"
                  class="record-item-icon"
                  src="/image/lottery-v3/winDetails-icon.svg"
                />
                <img
                  v-else
                  class="record-item-icon"
                  src="/image/lottery-v3/winDetails1-icon.svg"
                />
                <div class="record-item-text">
                  {{ $t("lotteryMoney.zjjl") }}
                </div>
              </div>
              <!-- 下注记录 -->
              <div
                v-if="Number(lotteryStore.activityCurStatus) == 5"
                class="record-item items-center"
                :class="{
                  'record-item-fri': lotteryStore.isFri,
                }"
                @click="jumpPage('dayBettingRecord')"
              >
                <img
                  v-if="!lotteryStore.isFri"
                  class="record-item-icon"
                  src="/image/lottery-v3/bettingRecord-icon.svg"
                />
                <img
                  v-else
                  class="record-item-icon"
                  src="/image/lottery-v3/bettingRecord1-icon.svg"
                />
                <div class="record-item-text">
                  {{ $t("lotteryMoney.blxzjl") }}
                </div>
              </div>
            </div>
          </van-pull-refresh>
        </ClientOnly>
        <!-- 底部 -->
        <div
          v-show="lottery && toDayIdx >= curDayIdx"
          class="footer items-center"
        >
          <!-- 下注按钮 -->
          <div class="footer-btn items-center" @click.stop="betClick">
            <img
              v-if="!isBetDisabled && !lotteryStore.isFri"
              class="footer-btn-bg"
              src="/image/lottery-v3/footer-btn-bg.svg"
            />
            <img
              v-else-if="isBetDisabled && !lotteryStore.isFri"
              class="footer-btn-bg"
              src="/image/lottery-v3/footer-btn-bg-disabled.png"
            />
            <img
              v-else-if="!isBetDisabled && lotteryStore.isFri"
              class="footer-btn-bg"
              src="/image/lottery-v3/footer-btn-bg1.svg"
            />
            <img
              v-else-if="isBetDisabled && lotteryStore.isFri"
              class="footer-btn-bg"
              src="/image/lottery-v3/footer-btn-bg-disabled1.png"
            />
            <div
              class="footer-btn-text"
              :class="{
                'footer-btn-text-disabled':
                  isBetDisabled && !lotteryStore.isFri,
                'footer-btn-text-disabled-fri':
                  isBetDisabled && lotteryStore.isFri,
                'footer-btn-text-minSize':
                  Number(lotteryStore.$state.freeDrawCount) > 0,
              }"
            >
              {{ betBtnTitle }}
            </div>
          </div>
        </div>
      </div>
      <!-- 中奖说明 -->
      <WinDescPopup
        v-if="isShowWinDesc"
        v-model:show="isShowWinDesc"
      ></WinDescPopup>
      <!-- 下注弹窗 -->
      <BetPopup
        v-if="isBetPopupShow"
        v-model:show="isBetPopupShow"
        :detail="betPopupInfo"
        @call="betPopupCall"
      ></BetPopup>
      <!-- 免费宝箱卡-->
      <freeCountdown
        v-if="
          isShowFreeCountdown &&
          Number(lotteryStore.$state.chestWlSource.recordStatus || 0) > 1
        "
        @countdownDone="freeCountdownClick(1)"
        @click.stop="freeCountdownClick(2)"
      ></freeCountdown>
      <!-- 开奖弹窗 -->
      <WinningResultPopup
        v-if="isShowWinningResult"
        v-model:show="isShowWinningResult"
        :source="winningSource"
        @winningCall="continueBet"
        @refresh="refreshWinningResult"
      ></WinningResultPopup>
      <!-- 结算弹窗 -->
      <SettlementPopup
        v-if="isShowWinningPopup"
        v-model:show="isShowWinningPopup"
        :source="settlementInfo"
        @open="settlementPopupOpened"
      ></SettlementPopup>
      <!-- 新用户福利领卡-弹窗 -->
      <userBenefitsPopup
        v-if="userBenefitsPopupShow"
        v-model:show="userBenefitsPopupShow"
        :type="userBenefitsPopupType"
        :nums="userBenefitsPopupNums"
        @confirm="userBenefitsPopupClick"
      />
      <!-- 无资格弹窗提示 -->
      <NotEligibleSundayPopup
        v-if="lottery && isEligibleSunday"
        v-model:show="isEligibleSunday"
        :lottery="lottery"
        @betCall="betWzgCall(2)"
        @inviteFriends="betWzgCall(1)"
      ></NotEligibleSundayPopup>
      <!-- 手动关闭活动,弹窗 -->
      <UpdatePopup
        v-if="isUpdatePopupShow"
        v-model:show="isUpdatePopupShow"
        :title="$t('lotteryMoney.hdyjs')"
        :desc="$t('lotteryMoney.bchdyjsjqqd')"
        :type="2"
      />
      <!-- 宝箱赠送免费卡弹窗 -->
      <ChestPopup
        v-if="chestPopupShow"
        v-model:show="chestPopupShow"
        @confirm="chestPopupShowClick"
      ></ChestPopup>

      <!-- 点击分享就可以领取奖励 -->
      <ChestSharePopup
        v-if="shareChestPopupShow"
        v-model:show="shareChestPopupShow"
        :num="isCanLqShareBox"
        @confirm="shareChestPopupShowClick"
      ></ChestSharePopup>

      <!-- 周五资格弹窗 -->
      <QualificationFri
        v-if="isShowQualificationFri"
        v-model:show="isShowQualificationFri"
        @confirm="qualificationFriCall"
      ></QualificationFri>
      <!-- 送 10次免费卡宝箱 -->
      <InviteFriendsRewardPopup
        v-if="isShowInviteFriendsReward"
        v-model:show="isShowInviteFriendsReward"
        :source="inviteFriendsOnceReward"
        @confirm="inviteFriendsRewardCall"
      ></InviteFriendsRewardPopup>
    </template>
  </div>
</template>
<script setup name="lotteryV3">
import * as MITO from "@zhj1214/qdjk-web";
import {
  getJackpotSessionInfo,
  syncServerTime,
  getUserJackpotResult,
  queryJackpotSimpleInfo,
  getJackpotBettingResult,
} from "@/api/lottery";
import { getJackpotLuckyReward } from "@/api/inviteFriends";
import { formatToTimeZone } from "@/utils/format";
import { JUMPAPPS } from "~/config";
import { useUserStore } from "~~/store/modules/user";
import { useGlobalStore } from "~~/store/global";
import { useLotteryV3Store } from "~~/store/modules/lottery-v3";
import { useEventBus, useDateFormat, useNetwork } from "@vueuse/core";
import { usePageVisibility } from "@vant/use";
import { useSocket } from "@/utils/useWebSocket";
import Jackpot from "@/components/lottery-v3/jackpot.vue";
import freeCountdown from "@/components/lottery-v3/lottery-free-countdown.vue";
import { getUserAccount } from "@/api/user";
import Decimal from "decimal.js";

// 中奖记录
const WinningRecord = defineAsyncComponent(() =>
  import("@/components/lottery-v3/winning-record.vue")
);

// 送你 10 张免费下注卡
const InviteFriendsReward = defineAsyncComponent(() =>
  import("@/components/lottery-v3/invite-friends-reward.vue")
);

// 邀友模块
const InviteFriendsView = defineAsyncComponent(() =>
  import("@/components/lottery-v3/invite-friends-view.vue")
);

// 历史中奖
const WinningHistoryRecord = defineAsyncComponent(() =>
  import("@/components/lottery-v3/winning-history-record.vue")
);

// 中奖结果
const winningResult = defineAsyncComponent(() =>
  import("@/components/lottery-v3/winning-result.vue")
);
/************************ start 弹窗 start ************************/
// 送你 10 张免费下注卡
const InviteFriendsRewardPopup = defineAsyncComponent(() =>
  import("~/components/lottery-v3/invite-friends-reward-popup.vue")
);
// 奖励说明弹窗
const WinDescPopup = defineAsyncComponent(() =>
  import("@/components/lottery-v3/win-desc-popup.vue")
);
// 下注弹窗
const BetPopup = defineAsyncComponent(() =>
  import("@/components/lottery-v3/bet-popup.vue")
);
// 开奖弹窗
const WinningResultPopup = defineAsyncComponent(() =>
  import("@/components/lottery-v3/winning-result-popup.vue")
);
// 结算弹窗: 优先级最高;
const SettlementPopup = defineAsyncComponent(() =>
  import("@/components/lottery-v3/settlement-result-popup.vue")
);
// 新人福利弹窗/每日抽奖 1 次福利
const userBenefitsPopup = defineAsyncComponent(() =>
  import("@/components/lottery-v3/user-benefits-popup.vue")
);

// 手动关闭活动弹窗
const UpdatePopup = defineAsyncComponent(() =>
  import("@/components/lotterymoney/update-popup.vue")
);
// 无资格弹窗
const NotEligibleSundayPopup = defineAsyncComponent(() =>
  import("@/components/lotterymoney/not-eligible-Sun-popup.vue")
);

// 宝箱赠送免费卡弹窗
const ChestPopup = defineAsyncComponent(() =>
  import("~/components/lottery-v3/chest-wlbx-popup.vue")
);

// 点击分享就可以领取奖励
const ChestSharePopup = defineAsyncComponent(() =>
  import("~/components/lottery-v3/chest-share-popup.vue")
);

// 周五资格弹窗
const QualificationFri = defineAsyncComponent(() =>
  import("@/components/lottery-v3/qualification-fri-popup.vue")
);
/************************ end 弹窗 end ************************/

/**
 * @description:  页面逻辑如下
 * 1. 在socket 建立之前,先获取一次需要的信息
 * 2. socket 成功建立在更新一次所有信息;在追加新的消息
 * 3. 页面销毁,关闭 socket
 * @author: zhj1214
 */

const globalStore = useGlobalStore();
// 如果没有登录-直接跳转登录页面
if (!globalStore.$state.token && process.client) {
  bridge.onAppLogin();
}

// store 状态
const userState = useUserStore();
const lotteryStore = useLotteryV3Store();
// 翻译
const { t } = useI18n();
// firebase埋点
const firebase = useInitFirebase(); // 初始化firebase
// 导航
const scrollEl = ref();

// 抽奖信息
const lottery = ref();

// 活动状态变更
const activityCurrentStatus_Watch = watch(
  () => lotteryStore.activityCurrentStatus,
  (newval, oldVal) => {
    console.warn(`activityCurrentStatus 活动状态更新: ${oldVal} => ${newval}`);
  }
);

const isPageInfoDone_watch = watch(
  () => lotteryStore.isPageInfoDone,
  (newVal, oldVal) => {
    if (process.client)
      console.warn("页面信息是否? 加载完成:", newVal ? "✅" : "❌");
  },
  {
    immediate: true,
  }
);
/************************ start 奖励说明 start ************************/
const isShowWinDesc = ref(false);
/************************ start 开奖弹窗 start ************************/
const isShowWinningResult = ref(false);
const winningSource = ref({});
// 继续下注
const continueBet = () => {
  isShowWinningResult.value = false;

  setTimeout(() => {
    // 1. 重置中奖结果,防止下次直接显示上一次的结果
    winningSource.value = null;
    // 2. 是否需要展示，分享宝箱，点击分享就可领取免费卡
    if (
      Number(isCanLqShareBox) > 0 &&
      Number(lotteryStore.$state.freeDrawCount) <= 0
    ) {
      shareChestPopupShow.value = true;
      return;
    }
    // 3. 继续下注
    betClick();
  }, 200);
};
/************************ start 送您 10次免费卡宝箱弹窗 start ************************/
const InviteFriendsViewSource = ref();
const inviteFriendsOnceReward = ref();
const isShowInviteFriendsReward = ref(false);
const isShowInviteFriendsRewardView = ref(true); // 是否展示奖励入口： 一个用户，只展示一次
const inviteFriendsRewardClick = () => {
  isShowInviteFriendsReward.value = true;
};
const inviteFriendsRewardCall = (freeDrawCount) => {
  isShowInviteFriendsRewardView.value = false; // 隐藏送 10 张免费卡
  isShowInviteFriendsReward.value = false; // 隐藏当前弹窗
  inviteFriendsOnceReward.value = null; // 重置送 10 张免费卡数据
  // 更新免费次数
  if (!validatenull(freeDrawCount)) {
    lotteryStore.$patch((state) => {
      state.freeDrawCount = freeDrawCount;
    });
  }
};
/************************ start socket start ************************/
let isSUBSCRIBEArr = ref([]); // 作用: 1.不会重复订阅  2. 查看订阅了哪些,后面还可以防止漏掉哪些订阅
let pongTimeout = 10000; // 超时时间
let connectedInterval = null; // 心跳定时器
let destinations = ["destination:/topic/", "destination:/user/"]; // 订阅的消息,才能去 JSON 转换,避免失败
let isThredFail = ref(false); // 6 次重连失败
let isContecting = false; // 是否已经正在链接 socket 了
let isCloseIng = false; // 是否正在关闭

// socket 链接建立
let onConnected = (ws) => {
  console.log("🔗 socket 建立链接, onConnected");
  // 1. ❗️由于vueuse封装中,没有心跳响应就会自动关闭链接,这里自行制造一条服务端的伪消息,欺骗客户端达到心态成功的目的;
  if (ws.onmessage) {
    connectedInterval = setInterval(() => {
      ws.onmessage("\n");
    }, pongTimeout - 7000); // 这里的心跳检测时间只要小于 5s,就能永远发送心跳;暂时设定 3 秒
  }
  // 2 重置订阅消息数组
  isSUBSCRIBEArr.value = [];
  // 3 发送成功建立链接的,消息
  send("CONNECT\naccept-version:1.1,1.0\nheart-beat:10000,10000\n\n\x00");
};
// 建立失败: 错误 code: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
let onError = (val) => {
  console.error("🔗 socket 链接建立失败 onError:", val);
  isContecting = false;
  isCloseIng = false;
  // 这里只提示一次: 为什么不是 6,因为 6 的时候有可能比较早,导致顶掉了其他消息
  if (tryCatchNums == 4) {
    showToast({
      message: t("common.wlycqcxjr"),
      "z-index": 9999999,
    });
  }
  if (tryCatchNums <= 4) {
    MITO.log({
      message: `${isPageVisibility} 🔗 socket 链接建立失败 第 ${
        6 - tryCatchNums
      } 次`,
      tag: "抽奖v3,手动上报错误",
      level: "high",
      ex: "手动",
    });
  }
};

// token: 由于无法增加请求头参数,message 增加,导致后端改动大,暂时放在连接中
const { open, data, status, close, send } = useSocket(
  `/bdc/lottery?token=${globalStore.$state.token}&language=${globalStore.$state.language}&Package-Id=${globalStore.$state.packageId}`,
  {
    message: "\n",
    interval: 10000,
    pongTimeout,
  },
  false, // recoveryFailedFn
  onConnected,
  onError
);

/**
 * 是否开始建立连接 Socket
 * */
const openSocket = () => {
  if (!process.client) return;
  if (status.value != "CLOSED") {
    return console.warn("🔗 socket 不是 CLOSED 状态无需 链接");
  }

  if (isContecting) {
    return console.warn("🔗 正在建立链接,请稍等..");
  }

  if (isCloseIng) {
    return console.warn("正在关闭,不能链接 socket");
  }
  //
  console.warn("🔗 调用 open 连接 socket");
  isContecting = true;
  open();
};

/**
 * @description: 关闭 socket
 * 1. 重置 stroe 中的状态
 */

const closeSocket = () => {
  if (!process.client) return;
  if (status.value != "OPEN") {
    return console.warn("🔗 socket 不是 open 状态无需关闭");
  }
  if (isCloseIng) return console.warn("正在关闭 socket");
  console.warn("调用 close 关闭 socket");
  // 1. 发送关闭消息
  send("DISCONNECT\n\n\x00");
  // 2. 重置 socket 数据
  lotteryStore.resetSocketData();
  // 3. 关闭,保证关闭消息发送出去,在调用
  isCloseIng = true;
  // 4. 关闭链接
  setTimeout(() => {
    close && close();
    isContecting = false;
  }, 100);
};

/**
 * socket 状态监听
 * */
let tryCatchNums = 6; // 重试次数
const tryCatchFn = () => {
  if (tryCatchNums >= 1) {
    if (!isContecting) {
      tryCatchNums -= 1;
      console.warn("🔗 socket,第", 6 - tryCatchNums, "次重试");
      openSocket();
    } else {
      console.warn("🔗 socket,正在重试,无需再次建立");
    }
  } else {
    isThredFail.value = true;
    lotteryStore.$patch((state) => {
      state.isThredFailSocket = true;
    });
    showToast({
      message: t("common.wlycqcxjr"),
      "z-index": 9999999,
    });
  }
};

const socketStatus_watch = watch(
  () => status.value,
  (newVal, oldVal) => {
    if (!process.client) return;
    console.warn("🔗 socket 状态变更: ", oldVal, "=>", newVal);
    // 1. 链接断联以后,重试链接
    if (newVal == "CLOSED" && oldVal == "OPEN") {
      isCloseIng = false;
      setTimeout(() => {
        tryCatchFn();
      }, 3000);
    }

    // 1.1 链接建立失败,重试链接
    if (oldVal == "CONNECTING" && newVal == "CLOSED") {
      isCloseIng = false;
      setTimeout(() => {
        tryCatchFn();
      }, 3000);
    }

    // 2. 如果链接成功,重新加载一次数据,稳定性的保证
    if (newVal == "OPEN" && oldVal == "CONNECTING") {
      isContecting = false;
      console.warn("🔗 socket 连接成功,重新加载一次数据,稳定性的保证");
      // 2.1 重置 socket 数据状态
      lotteryStore.resetSocketData();
      // 2.2 调用接口
      if (Number(serverTime.value) > new Date("2024/01/01").getTime()) {
        getJackpotSessionInfoRequest();
      }
      // 2.3 重置,重连数据
      isThredFail.value = false;
      tryCatchNums = 6;
    }
    // 3. 更新 socket 的链接状态
    lotteryStore.$patch((state) => {
      state.socketStatus = newVal;
    });
  },
  {
    immediate: true,
  }
);

/**
 * @description: socket 消息订阅
 * 1. 先订阅,订阅成功的消息 destination:/user/{sid}/topic/common
 * 2. 基于上面那个消息成功订阅了以后再订阅,其他广播和私人消息
 * 3. 如何间隔 10 秒没有订阅成功,就在重试一次,订阅成功就不再延迟重试订阅
 */
const subscribeMsgPub = {}; // 消息订阅发布者
const socketMesgSubscribe = () => {
  // 1. 初始化,消息订阅状态对象
  const subscribeSuccessStatus = {};
  // 1.1 消息订阅函数
  const msgSubscribeFn = (subscribeUrl, call) => {
    // 1. 添加到已发送的消息数组中
    isSUBSCRIBEArr.value.push(subscribeUrl);
    // 2. 保存这个消息的状态,方便后续查看是否成功
    subscribeSuccessStatus[subscribeUrl] = false;
    // 2.1 创建成功回调
    let timer = null;
    subscribeSuccessStatus[`call:${subscribeUrl}`] = () => {
      timer && clearTimeout(timer);
      call && call();
    };
    // 3. 发送消息
    send(subscribeUrl);
    // 4. 重试逻辑
    timer = setTimeout(() => {
      if (!subscribeSuccessStatus[subscribeUrl]) {
        console.error("订阅超时重新订阅", subscribeUrl);
        msgSubscribeFn(subscribeUrl, call);
      }
    }, 3000);
  };
  // 2. 接受订阅成功消息 call
  subscribeMsgPub["subscribeSuccess"] = (subscribeKey) => {
    console.log("subscribeSuccess 成功订阅:", subscribeKey);
    // 2.1 拼接 key
    const keyUrl = `SUBSCRIBE\nid:sub-0\ndestination:${subscribeKey}\n\n\x00`;
    // 2.1 更改状态
    subscribeSuccessStatus[keyUrl] = true;
    // 2.2 触发回调函数
    subscribeSuccessStatus[`call:${keyUrl}`] &&
      subscribeSuccessStatus[`call:${keyUrl}`]();
  };

  // 3. 开始订阅
  // let sid_watch = null;
  // if (status.value == "OPEN" && isSUBSCRIBEArr.value.length < 2) {
  //   // 3.1 获取sid
  //   const sid =
  //     userState.$state.sid ||
  //     localStorage.getItem(`${globalStore.$state.token}:sid`) ||
  //     "";
  //   console.log("获取订阅id:", sid);
  //   if (sid) {
  //     const otherMsg = () => {
  //       if (
  //         !isSUBSCRIBEArr.value.includes(
  //           "SUBSCRIBE\nid:sub-0\ndestination:/topic/bdc/jackpot\n\n\x00"
  //         )
  //       ) {
  //         // 下注消息/奖池数量变更消息/实时开奖结果消息推送
  //         msgSubscribeFn(
  //           "SUBSCRIBE\nid:sub-0\ndestination:/topic/bdc/jackpot\n\n\x00"
  //         );
  //       }
  //     };
  //     // 3.2 先订阅,订阅成功的回调消息
  //     msgSubscribeFn(
  //       `SUBSCRIBE\nid:sub-0\ndestination:/user/${sid}/topic/common\n\n\x00`,
  //       () => {
  //         otherMsg();
  //         sid_watch && sid_watch();
  //       }
  //     );
  //   } else {
  //     // 获取用户信息太慢了,导致错过了ws订阅时机,这里补偿一下
  //     sid_watch = watch(
  //       () => userState.$state.sid,
  //       (newVal, oldVal) => {
  //         // console.log(newVal, "_sid_watch:", oldVal);
  //         if (
  //           newVal &&
  //           newVal != oldVal &&
  //           status.value &&
  //           status.value == "OPEN"
  //         ) {
  //           if (isSUBSCRIBEArr.value.length < 2) {
  //             console.warn(
  //               "获取用户信息太慢了,导致错过了ws订阅时机,这里补偿一下"
  //             );
  //             // 3.2 先订阅,订阅成功的回调消息
  //             msgSubscribeFn(
  //               `SUBSCRIBE\nid:sub-0\ndestination:/user/${sid}/topic/common\n\n\x00`,
  //               () => {
  //                 otherMsg();
  //               }
  //             );
  //           }
  //         }
  //       }
  //     );
  //   }
  // }
  // 方案二: 直接订阅消息;
  if (status.value == "OPEN" && isSUBSCRIBEArr.value.length < 1) {
    // 1. 先订阅,订阅成功的回调消息
    msgSubscribeFn(
      "SUBSCRIBE\nid:sub-0\ndestination:/topic/bdc/jackpot\n\n\x00"
    );
    // 2. 默认订阅成功
    subscribeMsgPub["subscribeSuccess"] &&
      subscribeMsgPub["subscribeSuccess"]("/topic/bdc/jackpot");
  }
};

// 打印,消息订阅
const isSUBSCRIBEArr_watch = watch(
  () => isSUBSCRIBEArr.value,
  (newVal) => {
    console.log(
      useDateFormat(Date.now(), "YYYY-MM-DD HH:mm:ss").value,
      "订阅了哪些消息:",
      newVal
    );
  }
);

/**
 * @description: socket 消息回调处理逻辑
 * @param {*} obj 消息内容
 */
const socketMsgCall = (obj) => {
  /****************** 下注消息 ******************/
  if (obj.messageType == "bdcJackpotBetting" && obj.data) {
    // 1. 组装下注数据,并保存
    if (obj.data.detailList && obj.data.detailList.length > 0) {
      let arr = [];
      obj.data.detailList.forEach((e) => {
        arr.push({
          idsid: `${e.id}${obj.data.sid}`,
          sid: obj.data.sid,
          nickname: obj.data.nickname,
          avatar: obj.data.avatar,
          id: e.id,
          drawCount: e.drawCount,
          drawNo: e.drawNo,
          drawTime: e.drawTime,
        });
      });
      if (arr.length > 0) lotteryStore.addBetRecord(arr);
    }
    // 2. 奖池变更
    if (Number(obj.data.jackpotPoolAmount) > Number(moneyEnd.value)) {
      moneyEnd.value = Number(decimalToLength(obj.data.jackpotPoolAmount));
      setTimeout(() => {
        moneyStart.value = Number(decimalToLength(obj.data.jackpotPoolAmount));
      }, 500);
      // console.log("111moneyEnd.value: ", moneyEnd.value);
      // 更新奖池
      lotteryStore.$patch((state) => {
        const jcBdc = new Decimal(obj.data.jackpotPoolAmount || 0).mul(1000);
        // if (Number(jcBdc) > state.jackpotPoolAmountBdc) {
        state.jackpotPoolAmountBdc = Number(jcBdc);
        // }
      });
    }

    // 3. 是否显示奖池上限提示
    if (obj.data.reachMaxBdcIncrementAmountLimit == 1) {
      pool.value.isReachMax = 1;
    }
    return;
  }
  /****************** 奖池数量变更,特殊场景触发 ******************/
  if (obj.messageType == "bdcJackpotPoolAmountChange" && obj.data) {
    if (
      lottery.value.sessionId == obj.data.sessionId &&
      Number(obj.data.jackpotPoolAmount) > Number(moneyEnd.value)
    ) {
      moneyEnd.value = Number(decimalToLength(obj.data.jackpotPoolAmount));
      setTimeout(() => {
        moneyStart.value = Number(decimalToLength(obj.data.jackpotPoolAmount));
      }, 500);

      // 更新奖池
      lotteryStore.$patch((state) => {
        const jcBdc = new Decimal(obj.data.jackpotPoolAmount || 0).mul(1000);
        // if (Number(jcBdc) > state.jackpotPoolAmountBdc) {
        state.jackpotPoolAmountBdc = Number(jcBdc);
        // }
      });
    }
    return;
  }
  /****************** 实时开奖结果推送 ******************/
  if (obj.messageType == "bdcJackpotBettingResult" && obj.data) {
    // 1. 中奖数据,组装,并保存
    if (obj.data.detailList && obj.data.detailList.length > 0) {
      let list = [];
      obj.data.detailList.forEach((e) => {
        // 只有一等奖 和 二等奖,才会添加到中奖记录中
        if (e.prizeLevel == 1 || e.prizeLevel == 2) {
          list.push({
            idsid: `${e.id}${obj.data.sid}`,
            sid: obj.data.sid,
            nickname: obj.data.nickname,
            avatar: obj.data.avatar,
            hashScore: obj.data.hashScore,
            // transactionHash: obj.data.transactionHash,
            id: e.id,
            drawCount: e.drawCount,
            drawNo: e.drawNo,
            drawTime: e.drawTime,
            prizeType: e.prizeType,
            oneBetPrizeAmount: e.oneBetPrizeAmount,
            prizeLevel: e.prizeLevel,
          });
        }
      });
      if (list.length > 0) lotteryStore.addWinningRecord(list);
    }
    // 2. 如果是我下注的,要展示开奖结果页面
    if (userState.$state.sid == obj.data.sid) {
      // 2.1 特殊: 消息提前到,下注接口数据后到
      // 2.2 正常: 下注接口先到,中奖消息后到
      // 2.3 弹窗已经展示了,但是有多条中奖消息,只展示上一次下注的中奖结果
      if (isShowWinningResult.value) {
        if (
          winningSource.value &&
          obj.data.orderNo == winningSource.value.orderNo
        ) {
          winningSource.value = obj.data;
        }
      } else {
        winningSource.value = obj.data;
      }
    }
    // 3. 更新中奖数据
    lotteryStore.$patch((state) => {
      state.firstLevelPrizeDrawCount = obj.data.firstLevelPrizeDrawCount || 1;
      state.secondLevelPrizeDrawCount = obj.data.secondLevelPrizeDrawCount || 1;
    });
    return;
  }

  /****************** 活动关闭/开启消息 ******************/
  if (obj.messageType == "bdcJackpotPoolStatusChange" && obj.data) {
    // 1. 确定是不是当天这一期活动关闭/打开；是 => 在当天tab下 => 刷新界面 否无需处理
    if (obj.data.sessionId == lotteryStore.$state.sessionIdCur) {
      lotteryStore.$patch((state) => {
        state.sessionStatusCur = obj.data.sessionStatus;
      });
    }
    // 2. 如果 tab 是当天就刷新请求
    if (curDayIdx.value == toDayIdx.value) {
      getJackpotSessionInfoRequest(true);
    }
  }

  /****************** 挽留宝箱邀友消息 ******************/
  if (obj.messageType == "jackpotLuckyRewardTypeOne" && obj.data) {
    if (obj.data.sid == userState.$state.sid) {
      lotteryStore.$patch((state) => {
        state.chestWlSource = obj.data;
      });
      if (
        obj.data.limitInviteUserCount == obj.data.inviteUserCount &&
        Number(obj.data.claimEndTime) > Number(serverTime.value) &&
        obj.data.recordStatus == 3
      ) {
        chestPopupShow.value = true;
      }
    }
  }

  /****************** 赠送 10次免费卡注册的消息 ******************/
  if (obj.messageType == "jackpotLuckyRewardTypeThree" && obj.data) {
    if (obj.data.sid == userState.$state.sid) {
      if (!inviteFriendsOnceReward.value) {
        // 一般不会走到这里面
        inviteFriendsOnceReward.value = obj.data;
      }
      // 2. registerUserList 往这个里面追加一条用户信息
      else if (
        obj.data.registerUserList &&
        obj.data.registerUserList.length > 0
      ) {
        inviteFriendsOnceReward.value.registerUserList =
          obj.data.registerUserList;
        inviteFriendsOnceReward.value.recordStatus = obj.data.recordStatus;
      }
    }
  }
};
/**
 * socket 消息
 * */
const socketMsg_watch = watch(
  () => data.value,
  (newVal) => {
    // console.log("socket data:", newVal);
    if (!newVal) return;
    try {
      if (typeof newVal === "string") {
        // 1. 建立连接以后,开始订阅消息
        if (newVal.includes("CONNECTED\n")) {
          setTimeout(() => {
            socketMesgSubscribe();
          }, 50); // 调试,稳定方法
          return;
        }
        // 2. 消息处理
        if (
          newVal.includes(destinations[0]) ||
          newVal.includes(destinations[1])
        ) {
          // 2.1 消息转换
          let json = newVal.split("\n\n")[1];
          if (json) {
            const obj = JSON.parse(
              json
                .substring(0, json.length - 1)
                .replace(/\s/g, "")
                .replace(/\s/g, "\n")
                .replace(/\s/g, "\x00")
            );
            console.warn("🔗 socket 消息:", JSON.parse(JSON.stringify(obj)));
            // 2.2 订阅成功的回调
            if (obj.messageType == "subscribeSuccess" && obj.data) {
              subscribeMsgPub["subscribeSuccess"] &&
                subscribeMsgPub["subscribeSuccess"](obj.data.destination || "");
              return;
            }
            // 2.3 拦截处理
            if (!lotteryStore.isPageInfoDone) {
              return console.warn("未获取到页面信息,消息不处理");
            }
            if (
              lotteryStore.activityCurStatus != 2 &&
              obj.messageType != "bdcJackpotPoolStatusChange"
            ) {
              return console.warn(
                lotteryStore.activityCurStatus,
                "当前活动不是进行中,消息不处理"
              );
            }

            socketMsgCall(obj);
          }
        } else {
          console.log("❌未知订阅-消息类型 socket data:", newVal);
        }
      } else {
        console.log("❌未知消息类型 socket data:", newVal);
      }
    } catch (error) {
      console.error("socket data", error);
      MITO.log({
        message: `${isPageVisibility} socket 消息监听: ${error}`,
        tag: "抽奖v3,手动上报错误",
        level: "high",
        ex: "手动",
      });
    }
  },
  {
    immediate: true,
  }
);

/************************ end socket end ************************/
/**
 * @description: 切换日期
 */
const toDayIdx = ref(null);
const changeDay = throttle(
  (val) => {
    console.warn("切换日期:", val);
    // 1. 赋值
    toDayIdx.value = val;
    lotteryStore.$patch((state) => {
      state.toDayIdx = val;
    });

    day7.value.forEach((e) => {
      if (e.id == val) {
        e.isJh = true;
      } else {
        e.isJh = false;
      }
    });

    // 2.请求
    getJackpotSessionInfoRequest(true);
    // 3. 是不是周五
    if (val == 7) {
      if (curDayIdx.value != 7) {
        // 1. 有资格： 每天一次  2. 无资格，一直弹出来
        if (isFriBetZg.value) {
          const isHasPopup = localStorage.getItem(
            userState.$state.sid + "-" + "lotteryV3-isFriBetZg"
          );

          if (!isHasPopup || isHasPopup != lotteryStore.$state.sessionIdCur) {
            isShowQualificationFri.value = true;
            localStorage.setItem(
              userState.$state.sid + "-" + "lotteryV3-isFriBetZg",
              lotteryStore.$state.sessionIdCur
            );
          }
        } else {
          isShowQualificationFri.value = true;
          localStorage.setItem(
            userState.$state.sid + "-" + "lotteryV3-isFriBetZg",
            lotteryStore.$state.sessionIdCur
          );
        }
      }
    }
  },
  300,
  true
);

/**
 * 获取当前GTM+7 时间是周几,初始化日期数据
 * */
let day7 = ref([]);
const curDayIdx = ref(null); // 当前周几数字 1~7
const curDay = ref(null); // 当天数据
const initDate = () => {
  let time = Number(serverTime.value);
  if (time <= new Date("2024/01/01").getTime()) {
    time = Date.now();
  }
  const { week } = formatToTimeZone(new Date(time), "Asia/Jakarta", false);
  // 1. 赋值7 天数据
  day7.value = [
    {
      title: t("lotteryMoney.z6"),
      id: 1,
      isToDay: week == "Sat",
      isJh: week == "Sat",
    },
    {
      title: t("lotteryMoney.z7"),
      id: 2,
      isToDay: week == "Sun",
      isJh: week == "Sun",
    },
    {
      title: t("lotteryMoney.z1"),
      id: 3,
      isToDay: week == "Mon",
      isJh: week == "Mon",
    },
    {
      title: t("lotteryMoney.z2"),
      id: 4,
      isToDay: week == "Tue",
      isJh: week == "Tue",
    },
    {
      title: t("lotteryMoney.z3"),
      id: 5,
      isToDay: week == "Wed",
      isJh: week == "Wed",
    },
    {
      title: t("lotteryMoney.z4"),
      id: 6,
      isToDay: week == "Thu",
      isJh: week == "Thu",
    },
    {
      title: t("lotteryMoney.z5"),
      id: 7,
      isToDay: week == "Fri",
      isJh: week == "Fri",
    },
  ];

  // 2. 今天是周几
  day7.value.forEach((e) => {
    if (e.isToDay) {
      curDayIdx.value = e.id;
      toDayIdx.value = e.id;
      lotteryStore.$patch((state) => {
        state.toDayIdx = e.id;
      });
      curDay.value = e;
    }
  });
};

// 周五-是否有资格下注: 1. 累计下注次数不足 1 住; 2. 周日没有邀请好友 registerInviteUserCount
const isEligibilityZw = computed(() => {
  return (
    lottery.value &&
    lottery.value.jackpotType == 2 &&
    lottery.value.superPool.currentPeriodBdcDrawEnable == 1
  );
});

const isFriBetZg = computed(() => {
  return (
    lotteryStore.$state.currentPeriodBdcDrawEnable == 1 ||
    lotteryStore.$state.registerInviteUserCount > 0
  );
});

/**
 * 是否展示,中奖弹窗
 * 1. 每一期只展示一次;
 * 2. 展示时间: 当前时间 > 这期活动开奖时间 - 24*60*60*1000  (因为运营人员每天 10 点直播开(前一天)奖)
 * 3. 提前半小时保存数据,避免集中请求的场景
 * */
const isShowWinningPopup = ref(false);
const settlementInfo = ref(null); // 中奖信息
let periods = "";
// 弹窗显示回调: 展示以后再写入缓存
const settlementPopupOpened = () => {
  localStorage.setItem("lotteryV3SettlementIdLast", periods);
};
const isShowWinnerPopup = (isCountdownEnd) => {
  // isShowWinningPopup.value = true;
  // return;
  // 1. 获取缓存中: 上一次展示的期数
  const lotterySessionId = localStorage.getItem(
    userState.$state.sid + "-" + "lotteryV3SettlementIdLast"
  );
  // 1.1 计算上一期期数
  const { year, month, day } = formatToTimeZone(
    new Date(Number(serverTime.value) - 24 * 60 * 60 * 1000),
    "Asia/Jakarta",
    false
  );
  const periods = `${year}${month}${day}`;
  // console.log("G TM +7 上一期日期:", periods);

  // 1.1 上一期没有中奖
  if (
    lotterySessionId &&
    lotterySessionId.includes("no") &&
    lotterySessionId.includes(periods)
  ) {
    console.warn(periods, ": 没有中奖");
    return;
  }
  // 2. 缓存的期数与当前不一致: 请求结算结果
  if (!lotterySessionId || lotterySessionId != periods) {
    // 2.1 倒计时结束:缓存的有结果,直接显示
    if (settlementInfo.value && isCountdownEnd) {
      if (
        Number(serverTime.value) >=
        Number(lotteryStore.$state.sendPrizeTime) - 24 * 60 * 60 * 1000
      ) {
        console.warn(periods, ": 展示之前获取的结果");
        isShowWinningPopup.value = true;

        localStorage.setItem(
          userState.$state.sid + "-" + "lotteryV3SettlementIdLast",
          periods
        );
      }
    } else {
      console.warn("请求中奖信息 periods:", periods);
      getUserJackpotResult({
        selectDay: periods,
      }).then((res) => {
        // 2.1 期数 id - 缓存
        if (res) {
          if (res.myResult) {
            // 延迟的目的是为了等待 sendPrizeTime 赋值成功
            setTimeout(() => {
              // 提前半小时缓存结果,不展示
              if (
                Number(serverTime.value) >=
                  Number(lotteryStore.$state.sendPrizeTime) -
                    24.5 * 60 * 60 * 1000 &&
                Number(serverTime.value) <
                  Number(lotteryStore.$state.sendPrizeTime) -
                    24 * 60 * 60 * 1000 -
                    1000
              ) {
                settlementInfo.value = { ...res.myResult, periods };
                console.warn("保存中奖信息:", periods);
              }
              // 开奖以后,在弹窗: sendPrizeTime 代表今天这一期的开奖时间
              else if (
                Number(serverTime.value) >=
                Number(lotteryStore.$state.sendPrizeTime) - 24 * 60 * 60 * 1000
              ) {
                settlementInfo.value = { ...res.myResult, periods };
                isShowWinningPopup.value = true;
                localStorage.setItem(
                  userState.$state.sid + "-" + "lotteryV3SettlementIdLast",
                  periods
                );
              } else {
                console.warn("未到,开奖时间:", periods);
              }
            }, 500);
          } else {
            console.warn("未中奖 periods:", periods);
            setTimeout(() => {
              if (
                Number(serverTime.value) >=
                Number(lotteryStore.$state.sendPrizeTime) -
                  24.5 * 60 * 60 * 1000
              ) {
                localStorage.setItem(
                  userState.$state.sid + "-" + "lotteryV3SettlementIdLast",
                  `${periods}-no`
                );
                localStorage.setItem(
                  userState.$state.sid +
                    "-" +
                    "lotteryV3SettlementIdLastInfoTime",
                  Date.now()
                );
                localStorage.setItem(
                  userState.$state.sid + "-" + "lotteryV3SettlementIdLastInfo",
                  JSON.stringify(res)
                );
              }
            }, 500);
          }
        }
      });
    }
  }
};

// 活动结束时间
// const endTime = computed(() => {
//   // 1. 根据开始时间,设置结束时间
//   if (lottery.value && lottery.value.beginTime) {
//     return Number(lottery.value.beginTime) + +24 * 60 * 60 * 1000;
//   }

//   // 2. 创建一个新的 Date 对象，设置为当天的0 点
//   const now = new Date();
//   const curDate = new Date(
//     now.getFullYear(),
//     now.getMonth(),
//     now.getDate(),
//     0,
//     0,
//     0,
//     0
//   );
//   return curDate.getTime() + 24 * 60 * 60 * 1000;
// });

/**
 * @description: 查询抽奖信息
 */
const moneyStart = ref(0); // 奖池起始金额
const moneyEnd = ref(0); // 奖池结束金额

const sessionStatus = ref(null); // 活动状态(后端): 0:没有超级抽奖(特殊场景,手动关闭抽奖) 1:未开始 2:进行中 3:已结束(抽奖结果生成中) 5:已结束(抽奖结果已生成)
const pool = ref(null); // 奖池数据
// 是否正在请求
let isRequestLotteryInfo = false;
// 结算完成信息
const winningResultInfo = ref();
const getJackpotSessionInfoRequest = async (isLoading = false) => {
  if (isRequestLotteryInfo) return;
  // toDayIdx 不存在,导致请求错误数据;
  if (!toDayIdx.value) return;

  isRequestLotteryInfo = true;
  // 1. 是否需要 loadding
  if (isLoading) {
    showLoadingToast({
      message: `${t("common.requestIng")}...`,
      forbidClick: true,
      duration: 15000,
    });
  }
  // 2. 请求
  let selectId = toDayIdx.value ? toDayIdx.value : 1;
  const offsetDay = selectId - curDayIdx.value;
  const { year, month, day } = formatToTimeZone(
    new Date(Number(serverTime.value) + offsetDay * 24 * 60 * 60 * 1000),
    "Asia/Jakarta",
    false
  );

  const periods = `${year}${month}${day}`;
  // console.log("请求 periods:", periods);
  // console.log(selectId, "--", offsetDay, "--", curDayIdx.value);

  let res = await getJackpotSessionInfo({
    selectDay: periods,
    querySourceType: 1,
  });

  console.log("页面信息:", res);
  /******** start zhjdebugger start ********/
  // res = null;
  // 周5
  // res.jackpotType = 2;
  // res.periodId = res.sessionId;
  // res.sessionStatus = 3;
  // res.dailyBonusCount = 3;
  // res.maxSessionDrawCount = 100;
  // res.shareWithFriendFreeDrawCount = 7;
  /******** end zhjdebugger end ********/
  if (res) {
    // 1. 更新当天的,抽奖信息状态
    if (
      !lotteryStore.$state.isDoneLotteryInfo &&
      toDayIdx.value == curDayIdx.value
    ) {
      lotteryStore.$patch((state) => {
        state.isDoneLotteryInfo = true;
      });
    }
    // 2. 未开始,手动关闭,都是禁用状态
    if (Number(res.sessionStatus) < 2) {
      isBetDisabled.value = true;
    } else if (isBetDisabled.value) {
      isBetDisabled.value = false;
    }
    // 打印
    console.warn(
      "开始时间:",
      useDateFormat(Number(res.sessionTime), "YYYY-MM-DD HH:mm:ss").value
    );
    console.warn(
      "开奖时间:",
      useDateFormat(Number(res.sendPrizeTime), "YYYY-MM-DD HH:mm:ss").value
    );

    // 3. 赋值
    sessionStatus.value = res.sessionStatus;
    isCanLqShareBox = res.shareWithFriendFreeDrawCount || 0; // 不会根据期数变化，只代表今天能否领取
    lotteryStore.$patch((state) => {
      state.sessionStatus = res.sessionStatus;
      state.beginTime = res.sessionTime;
      state.sendPrizeTimeSelect = res.sendPrizeTime;
      state.sessionId = res.sessionId;
      state.periodId = res.periodId;
      state.jackpotType = res.jackpotType;
      state.maxSessionDrawCount = res.maxSessionDrawCount;
      state.inviteLotteryCode = res.inviteCode;
      state.firstLevelPrizeDrawCount = res.firstLevelPrizeDrawCount || 1;
      state.secondLevelPrizeDrawCount = res.secondLevelPrizeDrawCount || 1;
      if (
        res.superPool &&
        res.superPool.currentPeriodBdcDrawEnable != undefined
      ) {
        state.currentPeriodBdcDrawEnable =
          res.superPool.currentPeriodBdcDrawEnable;
      }
      state.registerInviteUserCount = res.registerInviteUserCount;

      // 更新奖池: 奖池变小也更新(不更新会导致周五切换到周一计算错误)
      const jcBdc = new Decimal(res.jackpotPoolAmount || 0).mul(1000);
      // if (Number(jcBdc) > state.jackpotPoolAmountBdc) {
      state.jackpotPoolAmountBdc = Number(jcBdc);
      // }
    });
    // 3.1 邀友奖励汇总
    if (res.invitePrize) {
      let mfxz = 0;
      let bdcCount = 0;
      let apy = 0;
      if (res.invitePrize.friendRegisterPrize) {
        mfxz += Number(res.invitePrize.friendRegisterPrize.inviteFreeDrawCount);
        bdcCount =
          Number(bdcCount) +
          Number(res.invitePrize.friendRegisterPrize.prizeAmount);
        apy =
          Number(apy) +
          Number(res.invitePrize.friendRegisterPrize.pledgeBonusRate);
      }
      if (res.invitePrize.friendFirstDepositPrize) {
        mfxz += Number(
          res.invitePrize.friendFirstDepositPrize.inviteFreeDrawCount
        );
        bdcCount =
          Number(bdcCount) +
          Number(res.invitePrize.friendFirstDepositPrize.prizeAmount);
        apy =
          Number(apy) +
          Number(res.invitePrize.friendFirstDepositPrize.pledgeBonusRate);
      }
      if (apy != 0) apy = new Decimal(apy).mul(100);

      InviteFriendsViewSource.value = {
        mfxz,
        bdcCount,
        apy,
      };
    }
    // 3.2 一次性的邀友奖励
    if (res.invitePrize && res.invitePrize.oneShotInviteFriendPrize) {
      inviteFriendsOnceReward.value = res.invitePrize.oneShotInviteFriendPrize;
    } else {
      isShowInviteFriendsRewardView.value = false;
    }

    // 活动当天,且在进行中的场景,才能去更新:下注记录和中奖记录
    if (curDayIdx.value == toDayIdx.value) {
      lotteryStore.$patch((state) => {
        state.sessionStatusCur = res.sessionStatus;
        state.sessionIdCur = res.sessionId;
        state.sendPrizeTime = res.sendPrizeTime;
        state.freeDrawCount = res.freeDrawCount;
        state.sessionDrawCount = res.sessionDrawCount; // 已经下注数量
        state.leftDrawCount =
          Number(res.maxSessionDrawCount) - Number(res.sessionDrawCount); // 剩余下注数量
      });
      // 下注记录
      const betRecordList =
        (res.recentDrawRecordList || []).map((e) => {
          e.idsid = `${e.id}${e.sid}`;
          return e;
        }) || [];

      if (betRecordList.length > 0 && res.sessionStatus == 2) {
        lotteryStore.addBetRecord(betRecordList);
      }

      // 中奖记录
      const recentPrizeRecordList =
        (res.recentPrizeRecordList || []).map((e) => {
          e.idsid = `${e.id}${e.sid}`;
          return e;
        }) || [];

      if (recentPrizeRecordList.length > 0 && res.sessionStatus == 2) {
        lotteryStore.addWinningRecord(recentPrizeRecordList);
      }
    } else {
      lotteryStore.$patch((state) => {
        state.freeDrawCount = 0;
        state.sessionDrawCount = 0; // 已经下注数量
        state.leftDrawCount = 0;

        state.betRecordList = [];
        state.betRecordListIds = [];
        state.recentPrizeRecordList = [];
      });
    }

    if (res.sessionResult) winningResultInfo.value = res.sessionResult;

    // 3.1 信息保存
    let lotteryInfo = {
      sessionId: res.sessionId,
      periodId: res.periodId,
      beginTime: res.sessionTime,
      newUserBonusCount: res.newUserBonusCount,
      jackpotType: res.jackpotType,
      superPool: res.superPool || {},
      registerInviteUserCount: res.registerInviteUserCount,
    };

    // 4. 奖池数据
    if (res.jackpotPoolAmount) {
      pool.value = {
        jackpotPoolAmount: res.jackpotPoolAmount,
        isReachMax: res.reachMaxBdcIncrementAmountLimit,
        maxBdcIncrementAmount: res.maxBdcIncrementAmount,
      };

      // 4.1 奖池滚动
      if (moneyStart.value == 0 && moneyEnd.value == 0) {
        moneyStart.value = Number(decimalToLength(res.jackpotPoolAmount));
        moneyEnd.value = Number(decimalToLength(res.jackpotPoolAmount));
      } else if (Number(res.jackpotPoolAmount) > moneyEnd.value) {
        moneyEnd.value = Number(decimalToLength(res.jackpotPoolAmount));
        setTimeout(() => {
          moneyStart.value = Number(decimalToLength(res.jackpotPoolAmount));
        }, 500);
      } else {
        moneyEnd.value = Number(decimalToLength(res.jackpotPoolAmount));
      }
    } else {
      moneyEnd.value = 0;
      moneyStart.value = 0;
      pool.value = {
        jackpotPoolAmount: 0,
        isReachMax: 0,
        maxBdcIncrementAmount: 1000,
      };
    }

    lottery.value = lotteryInfo;

    // 7. 是否展示,新用户免费弹窗
    if (!userBenefitsPopupShow.value) {
      // 新人
      if (res.newUserBonusCount && Number(res.newUserBonusCount) > 0) {
        userBenefitsPopupType.value = 1;
        userBenefitsPopupNums.value = Number(res.newUserBonusCount);
        userBenefitsPopupShow.value = true;
      }
      // 老用户每日
      else if (res.dailyBonusCount && Number(res.dailyBonusCount) > 0) {
        userBenefitsPopupType.value = 2;
        userBenefitsPopupNums.value = Number(res.dailyBonusCount);
        userBenefitsPopupShow.value = true;
      }
    }
  } else {
    lottery.value = {
      sessionId: 4,
    };
    pool.value = {
      jackpotPoolAmount: 0,
      isReachMax: 0,
      maxBdcIncrementAmount: 1000,
    };
    sessionStatus.value = 4;
    lotteryStore.$patch((state) => {
      state.sessionStatus = 4;
    });
  }
  // 重置状态
  isRequestLotteryInfo = false;
  return Promise.resolve();
};

/**
 * @description: 同步服务器时间
 */
const ckbzTime = new Date("2024/01/01").getTime(); // 创建一个特定时间的 Date 对象; 用于解决serverTime 初始值小于 1000 的场景
const serverTime = ref(ckbzTime);
const syncServerTimeFn = async () => {
  const res = await syncServerTime();
  if (res && res.nowMilli) {
    // 1. 是否更新时间
    if (Number(res.nowMilli) > Number(serverTime.value)) {
      serverTime.value = Number(res.nowMilli);
    }
  } else {
    // 延迟1秒后在执行后续逻辑;防止serverTime.value 的初始化值是 2024/01/01
    await new Promise((resolve) => {
      setTimeout(() => {
        resolve();
      }, 1500);
    });
  }
};

/**
 * @description: 页面刷新请求
 */
const refreshLoading = ref(false);
const onRefreshRequest = () => {
  try {
    console.warn("手动交互,下拉刷新了");
    refreshLoading.value = true;
    // 1.销毁所有数据
    // lotteryStore.destroy();
    // 2. 调用接口
    const a = getJackpotSessionInfoRequest();
    Promise.all([a]).finally(() => {
      refreshLoading.value = false;
    });
    // 更新挽留宝箱
    if (
      sessionStatus.value != 0 &&
      sessionStatus.value > 0 &&
      curDayIdx.value == toDayIdx.value
    ) {
      getJackpotLuckyRewardRequest();
    }
  } catch (error) {
    refreshLoading.value = false;
  }
};

/****************** start 活动状态变更 start ******************/
const isUpdatePopupShow = ref(false); // 手动关闭活动
const activityCurStatus_watch = watch(
  () => lotteryStore.activityCurStatus,
  (newVal, oldVal) => {
    console.warn("活动状态,从", oldVal, "变更", newVal);

    if (sessionStatus.value == 4) {
      console.log("请求失败,页面展示: activityCurStatus == 0 的场景");
    }
    // 展示升级中弹窗
    else if (newVal == 0 && sessionStatus.value == 0) {
      isUpdatePopupShow.value = true;
    }
  },
  {
    immediate: true,
  }
);

/****************** start 获取账户余额 start ******************/
const getUserAccountRequest = () => {
  getUserAccount().then((res) => {
    if (res) {
      userState.$patch((state) => {
        state.freeAmount = res.freeAmount;
      });
    }
  });
};

/****************** start 开奖,倒计时结束 start ******************/
const countdownCall = () => {
  console.warn("开奖倒计时结束");
  // 1. 更改状态
  if (winningResultInfo.value) {
    sessionStatus.value = 5;
    lotteryStore.$patch((state) => {
      state.sessionStatus = 5;
    });
  }
  // 2. 是否中奖
  if (!isShowWinningPopup.value) {
    isShowWinnerPopup(true);
  }
};
/****************** start 免费宝箱悬浮入口 start ******************/
const isShowFreeCountdown = ref(false);
// 1. 倒计时结束  2. 点击浮窗
const freeCountdownClick = (type) => {
  if (type == 1) {
    isShowFreeCountdown.value = false;
  } else {
    chestPopupShow.value = true;
  }
};
/****************** start 点击分享就可以领取奖励 start ******************/
let isCanLqShareBox = 0; // 今天是否，还可以领取分享宝箱
const shareChestPopupShow = ref(false); // 弹窗展示
const shareChestPopupShowClick = (freeDrawCount) => {
  shareChestPopupShow.value = false;
  isCanLqShareBox = 0;
  // 弹出分享桥接
  setTimeout(() => {
    inviteFriendsBridge.emit();
  }, 1000);
  if (!validatenull(freeDrawCount)) {
    lotteryStore.$patch((state) => {
      state.freeDrawCount = freeDrawCount;
    });
  }
};

/****************** start 宝箱赠送免费卡弹窗 start ******************/
const chestPopupShow = ref(false); // 弹窗展示
// type: 1 开箱 2.分享 3.领取
const chestPopupShowClick = (val) => {
  if (val.type == 1) {
    isShowFreeCountdown.value = true;
    lotteryStore.$patch((state) => {
      state.chestWlSource = val;
    });
  } else if (val.type == 2) {
  } else if (val.type == 3) {
    // 2. 剩余免费次数赋值
    lotteryStore.$patch((state) => {
      state.freeDrawCount = val.freeDrawCount;
    });

    chestPopupShow.value = false;
    isShowFreeCountdown.value = false;
  }
};
// 是否可以展示弹窗: type 1:接口拿到接口以后执行： 悬浮按钮逻辑，分享宝箱逻辑
const isCanShowChestPopup = (type) => {
  // 0. 获取，当天活动的状态；不是关闭状态，才可以继续执行下面代码
  if (lotteryStore.$state.sessionStatusCur == 0) return;

  // 0.1 展示分享宝箱： 今天没领取
  if (!type && Number(isCanLqShareBox) > 0 && !shareChestPopupShow.value) {
    shareChestPopupShow.value = true;
    return true;
  }

  if (lotteryStore.$state.chestWlSource.recordStatus == 1) {
    // 1. 是否要展示: 挽留宝箱 recordStatus == 1
    if (type != 1) {
      chestPopupShow.value = true;
      return true;
    }
    return;
  }
  // recordStatus == 2 && 当前时间 > endTimeAfter
  else if (lotteryStore.$state.chestWlSource.recordStatus == 2) {
    if (type == 1) {
      if (
        Number(serverTime.value) <
        Number(lotteryStore.$state.chestWlSource.endTime)
      ) {
        isShowFreeCountdown.value = true;
      }
    } else if (lotteryStore.$state.chestWlSource.endTimeAfter) {
      if (
        Number(serverTime.value) >
        Number(lotteryStore.$state.chestWlSource.endTimeAfter)
      ) {
        lotteryStore.$patch((state) => {
          state.chestWlSource = {
            recordStatus: 1,
          };
        });
        chestPopupShow.value = true;
        return true;
      } else {
        console.warn(
          "挽留宝箱",
          useDateFormat(
            Number(lotteryStore.$state.chestWlSource.endTimeAfter),
            "YYYY-MM-DD HH:mm:ss"
          ).value,
          "以后进入下一轮;"
        );
      }
    }
  }
  // recordStatus == 3 && 当前时间 > claimEndTimeAfter
  else if (lotteryStore.$state.chestWlSource.recordStatus == 3) {
    if (type == 1) {
      if (
        Number(serverTime.value) <
        Number(lotteryStore.$state.chestWlSource.claimEndTime)
      ) {
        isShowFreeCountdown.value = true;
      }
    } else if (lotteryStore.$state.chestWlSource.claimEndTimeAfter) {
      if (
        Number(serverTime.value) >
        Number(lotteryStore.$state.chestWlSource.claimEndTimeAfter)
      ) {
        lotteryStore.$patch((state) => {
          state.chestWlSource = {
            recordStatus: 1,
          };
        });
        chestPopupShow.value = true;
        return true;
      } else {
        console.warn(
          "挽留宝箱",
          useDateFormat(
            Number(lotteryStore.$state.chestWlSource.claimEndTimeAfter),
            "YYYY-MM-DD HH:mm:ss"
          ).value,
          "以后进入下一轮;"
        );
      }
    }
  }
  // recordStatus == 4 && 当前时间 > claimTimeAfter
  else if (lotteryStore.$state.chestWlSource.recordStatus == 4) {
    if (type == 1) {
      isShowFreeCountdown.value = false;
    } else if (lotteryStore.$state.chestWlSource.claimTimeAfter) {
      if (
        Number(serverTime.value) >
        Number(lotteryStore.$state.chestWlSource.claimTimeAfter)
      ) {
        lotteryStore.$patch((state) => {
          state.chestWlSource = {
            recordStatus: 1,
          };
        });
        chestPopupShow.value = true;

        return true;
      } else {
        console.warn(
          "挽留宝箱",
          useDateFormat(
            Number(lotteryStore.$state.chestWlSource.claimTimeAfter),
            "YYYY-MM-DD HH:mm:ss"
          ).value,
          "以后进入下一轮;"
        );
      }
    }
  }
};

const getJackpotLuckyRewardRequest = () => {
  // recordStatus: 1:待开启 2:进行中 3:待领取 4:已领取, 状态=1时, 其他字段都不存在
  getJackpotLuckyReward().then((res) => {
    /******** start zhjdebugger start ********/
    // res = {
    //   recordStatus: 1,
    // };
    /******** start zhjdebugger start ********/
    if (res) {
      lotteryStore.$patch((state) => {
        state.chestWlSource = res;
      });
      // 如果是待领取状态; 就主动弹出来
      if (
        res.recordStatus == 3 &&
        Number(res.claimEndTime) > Number(serverTime.value)
      ) {
        chestPopupShow.value = true;
      }
      // 悬浮弹窗逻辑
      isCanShowChestPopup(1);
    }
  });
};

/****************** start 周五资格弹窗 start ******************/
const isShowQualificationFri = ref(false);
// 记录缓存，弹出分享组件
const qualificationFriCall = () => {
  console.log("周五资格弹窗,弹窗回调");
  nextTick(() => {
    inviteFriendsBridge.emit();
  });
};

let isOnline_watch = null;
onMounted(async () => {
  // 网络断开,恢复; socket 重连逻辑; 写在 onMounted 里面是因为,在 setup 中,开发环境修改代码以后,会循环调用,耗费性能
  const { isOnline } = useNetwork();
  isOnline_watch = watch(
    () => isOnline.value,
    (newVal) => {
      if (!process.client) return;
      if (!newVal) {
        console.warn("网络断开, 尝试关闭 socket");
        close && closeSocket();
      } else {
        console.warn("网络正常, status关闭, 尝试连接 socket");
        open && openSocket();
      }
    },
    {
      immediate: true,
    }
  );

  // 1. 埋点
  firebase?.logEvent("BDC_H5_LotteryV3_PUV");
  // 2.获取服务时间,并初始化数据
  syncServerTimeFn().then(() => {
    if (day7.value.length == 0) {
      // 2.1 初始化时间
      initDate();
      // 2.2 获取抽奖信息
      getJackpotSessionInfoRequest(true).then(() => {
        // 2.3  余额
        getUserAccountRequest();
        // 2.4 是否中奖
        if (!isShowWinningPopup.value) {
          isShowWinnerPopup();
        }
        // 2.5 获取挽留宝箱数据; 活动结束不展示
        if (
          sessionStatus.value != 0 &&
          sessionStatus.value > 0 &&
          curDayIdx.value == toDayIdx.value
        ) {
          getJackpotLuckyRewardRequest();
        }
      });
    }
  });
  // 3. 拦截 APP 的返回事件
  globalStore.$patch((state) => {
    state.isInterceptAppBack = true;
  });
});

onBeforeUnmount(() => {
  activityCurrentStatus_Watch && activityCurrentStatus_Watch();
  isOnline_watch && isOnline_watch();
  isPageInfoDone_watch && isPageInfoDone_watch();
  isSUBSCRIBEArr_watch && isSUBSCRIBEArr_watch();
  socketMsg_watch && socketMsg_watch();
  pageVisibility_watch && pageVisibility_watch();
  socketStatus_watch && socketStatus_watch();
  activityCurStatus_watch && activityCurStatus_watch();

  // 0. store 销毁数据
  lotteryStore.destroy();
  // 1.注销通知
  moneyInterval.reset();
  inviteFriendsBridge && inviteFriendsBridge.reset();
  // moneyIntervalEmit && moneyIntervalEmit();
  // 2. 删除定时器
  serverTime_watch && serverTime_watch();
  // 3. 心跳定时
  connectedInterval && clearInterval(connectedInterval);
  // 3. 关闭 socket
  closeSocket();
  // 4. 重置 拦截 APP 的返回事件状态
  globalStore.$patch((state) => {
    state.isInterceptAppBack = false;
  });
});
/****************** start 下注弹窗 start ******************/
/**
 * @description: 更新剩余次数
 */
const queryJackpotSimpleInfoRequest = () => {
  queryJackpotSimpleInfo({
    sessionId: lotteryStore.$state.sessionId,
  }).then((res) => {
    console.log("查询剩余次数:", res);
    if (res) {
      lotteryStore.$patch((state) => {
        // 剩余次数
        if (state.leftDrawCount != res.leftDrawCount)
          state.leftDrawCount = res.leftDrawCount;
        // 剩余免费次数
        if (state.freeDrawCount != res.leftFreeDrawCount)
          state.freeDrawCount = res.leftFreeDrawCount;
      });
    }
  });
};

const isBetPopupShow = ref(false);
const betPopupInfo = reactive({});
/**
 * @description: 下注弹窗回调
 * @param {*} type  1. 成功 2.失败
 */
const betPopupCall = ({
  type,
  freeDrawCount,
  numbers5,
  orderNo,
  leftDrawCount,
}) => {
  // 下注成功
  if (type == 1) {
    // 下注成功,下注数量+1, 并且提示下了几注;
    showToast(t("lotteryMoney.xzcg"));
    lotteryStore.$patch((state) => {
      state.freeDrawCount = freeDrawCount;
      state.leftDrawCount = leftDrawCount;
    });
    // socket没有建立连接的时候,兜底: 更新界面信息
    if (status.value != "OPEN") getJackpotSessionInfoRequest();
    // 展示开奖页面
    if (!winningSource.value) {
      winningSource.value = {
        sid: userState.$state.sid,
        hashScore: "",
        orderNo: orderNo,
        detailList: numbers5.map((e) => {
          e.drawNo = e.numArr.join("");
          e.drawCount = e.stepper;
          e.prizeStatus = 1;
          return e;
        }),
      };
    } else if (winningSource.value.orderNo != orderNo) {
      winningSource.value = {
        sid: userState.$state.sid,
        hashScore: "",
        orderNo: orderNo,
        detailList: numbers5.map((e) => {
          e.drawNo = e.numArr.join("");
          e.drawCount = e.stepper;
          e.prizeStatus = 1;
          return e;
        }),
      };
    }

    isShowWinningResult.value = true;
  }
  // 请求失败,或者超时,请重试
  else if (type == 2) {
    showToast({
      message: t("lotteryMoney.xzsbqcs"),
      forbidClick: true,
    });
  }
};
/****************** start 抽奖按钮状态 start ******************/
const isBetDisabled = ref(false);
// 根据时间,判断活动是否未开始,未开始显示禁用状态;
const btnStatusChange = (time) => {
  if (time && lottery.value) {
    if (
      Number(time) < Number(lottery.value.beginTime) &&
      sessionStatus.value < 2
    ) {
      isBetDisabled.value = true;
    } else if (lotteryStore.activityCurStatus == 1) {
    }
  }
};
/****************** start 页面主逻辑,监听服务器时间 start ******************/

const moneyInterval = useEventBus("lottery-v3-interval-emit");
// moneyIntervalEmit = moneyInterval.on((val) => {})
const serverTime_watch = watch(
  () => globalStore.$state.serverTime,
  (newValue, oldValue) => {
    // console.log(newValue, "--serverTime_watch--", oldValue);
    if (newValue < ckbzTime) return;
    // 1. 更新时间
    if (newValue > serverTime.value) {
      serverTime.value = newValue;
    } else {
      serverTime.value += 1000;
    }
    // 2. 变更通知
    moneyInterval.emit(newValue);
    // 3. 每秒更新按钮状态
    btnStatusChange(newValue);
  },
  {
    immediate: true,
  }
);

/****************** start 页面可见状态 start ******************/
const pageVisibility = usePageVisibility();
let isPageVisibility = "visible"; // 默认是可见状态
const pageVisibility_watch = watch(pageVisibility, (value) => {
  // console.log("从后台进入前台: 刷新数据 ", value);
  // 1. 记录当前状态
  isPageVisibility = value;
  // 2. 进入后台
  if (value == "visible") {
    console.warn("从后台进入前台");
    // 2.1 更改状态,下次进入,刷新页面所有数据
    // 2.2 请求数据
    syncServerTimeFn().then(() => {
      getJackpotSessionInfoRequest(true).then((res) => {
        // 2.3 是否重新链接 socket
        if (lottery.value && status.value == "CLOSED") {
          console.warn("进入前台以后, status关闭, 尝试连接 socket");
          openSocket();
        }
        // 更新挽留宝箱
        if (
          sessionStatus.value != 0 &&
          sessionStatus.value > 0 &&
          curDayIdx.value == toDayIdx.value
        ) {
          getJackpotLuckyRewardRequest();
        }
      });
    });
  }
  // 3. 进入前台
  else {
    console.warn("此刻,从前台进入后台:", Date.now());
  }
});

/****************** start 自定义返回 start ******************/
const handleBack = () => {
  // 1. 是否要展示: 挽留宝箱 recordStatus == 1 && 当前时间 > endTime
  const isJump = isCanShowChestPopup();
  // 是否跳过下面逻辑
  if (isJump) return;

  // 2. 返回
  if (!window.history.state.back) {
    navigateI18nTo({
      path: "/activity",
    });
  } else {
    navigateBack(-1);
  }
};

const handleClose = () => {
  // 1. 是否要展示: 挽留宝箱 recordStatus == 1 && 当前时间 > endTime
  const isJump = isCanShowChestPopup();
  // 是否跳过下面逻辑
  if (isJump) return;
  // 2. 返回
  navigateBack(-1, true);
};

/****************** start 新用户福利,领卡弹窗 start ******************/
const userBenefitsPopupShow = ref(false);
const userBenefitsPopupType = ref(2); // 1 新人   2 每日
const userBenefitsPopupNums = ref(0); // 数量
const userBenefitsPopupClick = (val) => {
  // 1. 隐藏弹窗
  userBenefitsPopupShow.value = false;

  // 2. 剩余免费次数赋值
  lotteryStore.$patch((state) => {
    state.freeDrawCount = val;
  });
};

/****************** 下注按钮 ******************/

// 下注按钮文案
const betBtnTitle = computed(() => {
  // 手动关闭活动
  if (lotteryStore.activityCurStatus == 0) {
    return t("lotteryMoney.yjs");
  }
  // 未开始
  else if (lotteryStore.activityCurStatus == 1) {
    return t("lotteryMoney.wks");
  }
  // 其他都可以点击: 立即下注
  else {
    if (lottery && lotteryStore.$state.freeDrawCount) {
      return t("lotteryMoney.mfxzcs").replace(
        "x",
        lotteryStore.$state.freeDrawCount
      );
    } else {
      return t("lotteryMoney.ljxz");
    }
  }
});

/**
 * @description: 下注按钮
 */
const isEligibleSunday = ref(false); // 无资格参加周日活动

const betClick = debounce(
  () => {
    // 禁用按钮,禁止点击
    if (isBetDisabled.value) return;
    // 活动进行中
    if (lotteryStore.activityCurStatus == 2) {
      // 0. 下注前.重置中奖结果
      winningSource.value = null;
      // 1. 周五资格判断
      if (toDayIdx.value == 7 || lottery.value.jackpotType == 2) {
        // 无资格
        if (!isEligibilityZw.value) {
          const zgday = localStorage.getItem(
            userState.$state.sid + "-" + "lotteryv3-isEligibleday-money-bet"
          );
          // 无资格提示,显示一次
          if (!zgday) {
            isEligibleSunday.value = true;
            return;
          }
          // 展示过了
          else {
            // 确认是不是这周五弹出的,不是则还要弹出来
            const { year, month, day } = formatToTimeZone(
              new Date(Number(serverTime.value)),
              "Asia/Jakarta",
              false
            );
            const curDay = `${year.substring(2)}${month}${day}`;

            // console.log('zgday:',curDay);
            if (zgday != curDay) {
              isEligibleSunday.value = true;
              return;
            }
            // 当天的,且已经展示过了; 判断是不是邀友成功,没有则不能BDC下注,只能美金下注
            else if (
              !lottery.value.registerInviteUserCount ||
              lottery.value.registerInviteUserCount <= 0
            ) {
              lotteryStore.$patch((state) => {
                state.isFriDollarBet = true;
              });
            }
          }
        }
      }
      // 展示下注弹窗
      queryJackpotSimpleInfoRequest(); //  剩余次数校验
      isBetPopupShow.value = true;
    }
    // 活动已结束,点击下注,跳转到: 正在进行中的这一期
    else if (
      lotteryStore.activityCurStatus == 3 ||
      lotteryStore.activityCurStatus == 5
    ) {
      if (toDayIdx.value < 7) {
        changeDay(curDayIdx.value);
      }
      // 周五过了 23:59:59 活动开奖中,但是一直停留在这个页面
      else {
        // 重新计算日期
        initDate();
        // 在切换
        changeDay(curDayIdx.value);
      }
    }
  },
  500,
  false
);

/**
 * @description: 无资格:弹窗回调
 * @param {*} val 1 邀请好友  2 美金下注
 */
const inviteFriendsBridge = useEventBus("lottery-v3-inviteFriends-bridge-emit");
const betWzgCall = (val) => {
  isEligibleSunday.value = false;
  // 保存值,保证只弹出一次
  localStorage.setItem(
    userState.$state.sid + "-" + "lotteryv3-isEligibleday-money-bet",
    lottery.value.sessionId
  );
  if (val == 1) {
    // jumpPage("inviteFriendsMonery");
    nextTick(() => {
      inviteFriendsBridge.emit();
    });
  } else if (val == 2) {
    lotteryStore.$patch((state) => {
      state.isFriDollarBet = true;
    });
    queryJackpotSimpleInfoRequest(); //  剩余次数校验
    isBetPopupShow.value = true;
  }
};
/****************** start 页面跳转 start ******************/
const jumpPage = async (type, isApp = false) => {
  if (isApp) {
    if (type === "taskCenter") {
      firebase?.logEvent("BDC_H5_Mining_TaskCenter_Click"); // 埋点访问
      bridge.jumpAppRoute(JUMPAPPS()[type]);
    }
  } else if (type === "lotteryDesc") {
    firebase?.logEvent("BDC_H5_LotteryMoney_Desc_PUV"); // 埋点访问
    await navigateI18nTo({ path: "/lottery-v3/desc" });
  } else if (type === "bdcToMoney") {
    firebase?.logEvent("BDC_H5_LotteryMoney_BDCToMoney_Click"); // 埋点访问
    await navigateI18nTo({ path: "/lottery-v3/bdc-to-money" });
  } else if (type == "dayBettingRecord") {
    if (!lottery.value.sessionId) return;
    navigateI18nTo({
      path: "/lottery-v3/day-betting-record",
      query: {
        sessionId: lottery.value.sessionId,
      },
    });
  } else if (type == "previousDraws") {
    firebase?.logEvent("BDC_H5_previousDrawsV3_PUV");
    navigateI18nTo({
      path: "/lottery-v3/previous-record",
      query: {
        sessionId: lottery.value.sessionId,
      },
    });
  } else if (type == "myBetRecord") {
    firebase?.logEvent("BDC_H5_v3_myBetRecord_PUV");
    navigateI18nTo({
      path: "/lottery-v3/my-bet-record",
      query: {
        sessionId: lottery.value.sessionId,
      },
    });
  } else if (type === "winDetails") {
    firebase?.logEvent("BDC_H5_LotteryV3_winDetails_Click");
    await navigateI18nTo({
      path: "/lottery-v3/day-winning-details",
      query: {
        sessionId: lottery.value.sessionId,
      },
    });
  }
};

/**
 * 点击重试
 * 1. 请求失败
 * 2. socket 6 次链接失败
 * */
const refreshClick = debounce(
  () => {
    // 1. 是不是请求失败
    if (sessionStatus.value == 4) {
      // 1.获取服务时间,并初始化数据
      syncServerTimeFn().then(() => {
        // 1.1 更改状态,下次进入,刷新页面所有数据
        lotteryStore.resetLotteryData();
        // 1.2 初始化时间
        initDate();
        // 1.3 获取抽奖信息
        getJackpotSessionInfoRequest(true).then(() => {
          // 1.4  余额
          getUserAccountRequest();
        });
      });
    }
    // 2. 是否 socket 建立失败
    if (isThredFail.value) {
      tryCatchNums = 6;
      isThredFail.value = false;
      lotteryStore.$patch((state) => {
        state.isThredFailSocket = false;
      });
      tryCatchFn();
    }
  },
  1000,
  false
);
// 查询开奖结果：
const refreshWinningResult = (val) => {
  isShowWinningResult.value = false;
  // 1. 请求中奖结果
  if (val == 1) {
    getJackpotBettingResult({
      sessionId: lotteryStore.$state.sessionId,
      orderNo: winningSource.value.orderNo,
    }).then((res) => {
      console.log("查询开奖结果:", res);
      if (res) {
        if (res.transactionHash) {
          winningSource.value = res;
        } else {
          showToast({
            message: t("lotteryMoney.xzslzqnxdd"),
            "z-index": 9999999,
          });
        }
      }
    });
  }
  // 2. 执行主页,刷新逻辑
  else if (val == 2) {
    refreshClick();
  }
  // 3. 判断是否展示分享弹窗
  else if (val == 3) {
    if (
      Number(isCanLqShareBox) > 0 &&
      Number(lotteryStore.$state.freeDrawCount) <= 0
    ) {
      shareChestPopupShow.value = true;
      return;
    }
  }
};
</script>

<style lang="scss" scoped>
.lottery {
  position: relative;
  height: 100vh;
  overflow-y: scroll;
  overflow-x: hidden;
  will-change: scroll-position;
  padding-bottom: calc(var(--safe-area-inset-bottom) + 60 * 2px);
  background: #e5f2ff;

  &-fri {
    background: #fdf4dd !important;
  }
  &-bg {
    position: absolute;
    top: 0;
    left: 0px;
    width: 100vw;
    height: 366 * 2px;
    background: linear-gradient(180deg, #1a88ff 0%, #98dcff 40%, #98dcff 100%);
    &-end {
      height: 305 * 2px;
      background: linear-gradient(180deg, #1a88ff 0%, #daf3ff 100%);
    }
    &-fri {
      background: linear-gradient(
        180deg,
        #fda82b 0%,
        #ffe49e 40%,
        #ffe49e 100%
      ) !important;
    }
  }

  &-wait {
    position: relative;
    padding: 6 * 2px 15 * 2px;
    z-index: 9;
    background: rgba(0, 123, 255, 0.3);
    backdrop-filter: blur(12px);
    justify-content: space-between;
    &-sun {
      background: rgba(204, 122, 0, 0.3);
    }
    &-icon {
      width: 16 * 2px;
      height: 16 * 2px;
      margin-right: 4 * 2px;
    }
    &-text {
      color: #fff;
      font-size: 13 * 2px;
      &-sun {
        color: #fff;
      }
    }
    &-btn {
      width: 22 * 2px;
      height: 22 * 2px;
    }
  }

  // 兑换入口
  &-redemption {
    position: absolute;
    z-index: 9;
    top: 45 * 2px;
    left: 15 * 2px;
    width: 30 * 2px;
    height: 30 * 2px;
  }

  // 说明入口
  &-desc {
    position: absolute;
    z-index: 9;
    top: 45 * 2px;
    right: 15 * 2px;
    width: 30 * 2px;
    height: 30 * 2px;
  }
}

.date {
  justify-content: space-between;
  position: relative;
  z-index: 1;
  width: calc(100% - 15 * 4px);
  height: 58 * 2px;
  margin: 11 * 2px 15 * 2px 5 * 2px 15 * 2px;

  &-week {
    position: relative;
    z-index: 9;
    width: 100%;
    padding: 3 * 2px 6 * 2px;
    // border-radius: 4 * 2px 4 * 2px 0 0;
    border-radius: 4 * 2px;
    height: 36 * 2px;
    background: linear-gradient(180deg, #c2dfff 0%, #fff 49.85%, #c2dfff 100%);
    &-fri {
      background: linear-gradient(
        180deg,
        #f4f4f4 0%,
        #fff 49.85%,
        #f4f4f4 100%
      );
    }
  }
  &-shadow {
    position: absolute;
    z-index: 1;
    width: 100%;
    left: 0;
    bottom: 0;
    height: 46 * 2px;
    background: linear-gradient(180deg, #007bff 0%, rgba(0, 123, 255, 0) 100%);
    &-fri {
      background: linear-gradient(
        180deg,
        rgba(0, 0, 0, 0.3) 0%,
        rgba(255, 255, 255, 0) 100%
      );
    }
  }

  &-item {
    position: relative;
    justify-content: center;
    min-width: 48 * 2px;
    height: 18 * 2px;
    color: #002853;
    font-size: 13 * 2px;
    font-weight: 510;
    text-align: center;

    &-sub {
      position: relative;
      z-index: 9;
      &-jhbg {
        position: absolute;
        z-index: 1;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }
    &-cur {
      border-radius: 100px;
      background: rgba(0, 125, 255, 0.15);
    }
    &-jh {
      color: #fff;
      width: 69 * 2px;
      height: 24 * 2px;
      font-size: 15 * 2px;
      font-weight: 700;
    }
    &-fri {
      position: relative;
      color: #ff4040;
      border-radius: 100px;
      background: rgba(255, 64, 64, 0.15);
      &-tag {
        position: absolute;
        z-index: 11;
        height: 18 * 2px;
        top: -15.5 * 2px;
        left: 50%;
        transform: translateX(-50%);
      }
      &-jh {
        color: #fff;
        width: 69 * 2px;
        height: 24 * 2px;
        font-size: 15 * 2px;
        font-weight: 700;
      }
    }
  }
}

.record {
  background-color: #fff;
  justify-content: space-between;
  padding: 10 * 2px;
  margin: 0 15 * 2px;
  border-radius: 12 * 2px;
  margin-bottom: 10 * 2px;
  &-item {
    flex-direction: column;
    justify-content: center;
    padding: 4 * 2px;
    border-radius: 4 * 2px;
    background: #f2f8ff;
    width: 159 * 2px;
    &-fri {
      background: #fffaf2;
    }
    &-icon {
      width: 24 * 2px;
      height: 24 * 2px;
      margin-bottom: 4 * 2px;
    }
    &-text {
      color: #141924;
      text-align: center;
      font-size: 12 * 2px;
    }
  }
}
.footer {
  position: fixed;
  z-index: 99;
  bottom: 0;
  width: 100vw;
  justify-content: center;
  padding-bottom: var(--safe-area-inset-bottom);
  background-color: #fff;

  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);

  &-btn {
    position: relative;
    margin: 6 * 2px 15 * 2px;
    justify-content: center;
    width: 100%;
    height: 50 * 2px;

    &-bg {
      position: absolute;
      // top: 6 * 2px;
      // left: 15 * 2px;
      width: 100%;
      // height: 100%;
      object-fit: cover;
    }

    &-text {
      position: relative;
      z-index: 9;
      color: #fff;
      font-size: 17 * 2px;
      font-weight: 590;
      white-space: nowrap;
      &-minSize {
        font-size: 16 * 2px;
      }
      &-disabled {
        color: #6997ca;
        &-fri {
          color: #caa369;
        }
      }
    }
  }
}
</style>
